package org.xtremeobjects.domain.model;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

import org.xtremeobjects.anotations.ddd.Repository;

import com.google.inject.Inject;

@Repository( root = Clazz.class )   
public class ClazzRepository  implements org.xtremeobjects.domain.model.ddd.Repository {
	static private List<Clazz> clazzes;

	private List<Clazz> getClazzes() {
		if(clazzes == null) {
			clazzes = new ArrayList<Clazz>();
			initialize(clazzes);
		}
		return clazzes;
	}
	
	private ClazzFactory clazzFactory;
	
	@Inject
	public ClazzRepository(ClazzFactory clazzFactory) {
		this.clazzFactory = clazzFactory;
	}

	public Clazz findOrCreateByName(String name) throws ClassNotFoundException {

		for (Clazz clazz : allInstances()) {
			if(clazz.getName().equals(name))
				return clazz;
		}
		Clazz newClazz = clazzFactory.createFrom(name);
		getClazzes().add(newClazz);
		return newClazz;
	}

	private void initialize(List<Clazz> clazzes) {
		this.findOrCreateByClass(org.xtremeobjects.domain.model.Clazz.class);
		this.findOrCreateByClass(org.xtremeobjects.domain.model.Association.class);
		this.findOrCreateByClass(org.xtremeobjects.domain.model.Property.class);
	}

	public Clazz findOrCreateByClass(Class<?> javaClass) {
		for (Clazz clazz : allInstances()) {
			if(clazz.getImplementationClass().equals(javaClass))
				return clazz;
		}
		Clazz newClazz = clazzFactory.createFrom(javaClass);
		getClazzes().add(newClazz);
		return newClazz;
	}
	
	public List<Clazz> allInstances() {
		return Collections.unmodifiableList(new ArrayList<Clazz>(getClazzes()));
	}

	public void addObject(Object anObject) {
		// TODO Auto-generated method stub
		
	}

	public void addObject(Collection<?> anObjectCollection) {
		throw new RuntimeException("Not Supported");
	}

	public Object findObjectById(String anId) {
		// TODO Auto-generated method stub
		throw new RuntimeException("Not Supported");
//		return null;
	}

	public void removeObject(Object anObject) {
		// TODO Auto-generated method stub
		throw new RuntimeException("Not Supported");
		
	}

	public void removeObject(Collection<?> anObjectCollection) {
		// TODO Auto-generated method stub
		throw new RuntimeException("Not Supported");
		
	}

	public void updateObject(Object anObject) {
		// TODO Auto-generated method stub
		throw new RuntimeException("Not Supported");
		
	}

	public void updateObject(Collection<?> anObjectCollection) {
		// TODO Auto-generated method stub
		throw new RuntimeException("Not Supported");
		
	}

	public boolean canRemove() {
		return false;
	}

	public boolean canAdd() {
		return false;
	}
	
}
